package cn.getech.data.development.utils;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.hive.visitor.HiveSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * @description: sql语句解析 获取字段和表名
 * @author: wangzhaowen：kiss
 * @create: 2020/8/6 13:57
 * @version: 2020/8/6
 **/
public class SqlParseUtil {

    private static Logger logger = LoggerFactory.getLogger(SqlParseUtil.class);

    /**
     *
     * @param sql
     * @param dbType @see{JdbcConstants.MYSQL}
     * @return
     */
    public static String verifySql(String sql, String dbType) {
        try {
            SQLUtils.parseStatements(sql, dbType);
            //只要解析不出现错误就算成功
        } catch (Exception e) {
            logger.error("sql校验错误:{}", sql, e);
            return e.getMessage();
        }
        return null;
    }

    /**
     * hive sql语句解析
     *
     * @param sql hive sql语句
     */
    public static QueryTable parseHiveql(String sql) {
        Set<String> tableNames = new HashSet<>();
        Set<String> columnNames = new HashSet<>();
        try {
            List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.HIVE);
            for (SQLStatement sqlStatement : stmtList) {
                HiveSchemaStatVisitor visitor = new HiveSchemaStatVisitor();
                sqlStatement.accept(visitor);
                Map<TableStat.Name, TableStat> tabMap = visitor.getTables();
                for (TableStat.Name name : tabMap.keySet()) {
                    tableNames.add(name.getName());
                }
                for (TableStat.Column column : visitor.getColumns()) {
                    columnNames.add(column.getFullName());
                }
                //获取字段名称
            }
        } catch (Exception e) {
            logger.error("hive sql:{}解析错误：",sql,e);
        }
        return new QueryTable(tableNames, columnNames);
    }



    public static String generateSql(Set<String> columnNames, String tableName) {
        String sql = "select ";
        for (String columnName : columnNames) {
            sql = sql + " " + columnName + ",";
        }
        sql = sql.substring(0, sql.length() - 1);
        sql = sql + "  from " + tableName;
        return sql;
    }

    /**
     * 去除sql中注释语句
     */
    public static String wrapSql(String sql){
        Pattern p = Pattern.compile("(?ms)('(?:''|[^'])*')|--.*?$|/\\*.*?\\*/|#.*?$|");
        return p.matcher(sql).replaceAll("$1");
    }

//    public static void main(String[] args) {
//        String sql = "-- 更新数据\n" +
//                "UPDATE `bdp-admin`.`bdp_real_time_task` SET `task_type` = 1 WHERE `task_type`= 2 or task_type is null;\n" +
//                "/*  insert into report.partner_open_account_stat_tmp\n" +
//                "  -- where to_number(to_char(a.create_date,'YYYYMMDD'),'99999999') <= v_period_id\n" +
//                "*/ -- delete by zak 20140623";
//        System.out.println(wrapSql(sql));
//    }

    public static class QueryTable {
        private Set<String> tableFullNames;// 完整表名  包含库名  db.table_name
        private Set<String> columnNames;// 整的字段名称  db.table_name.column


        public QueryTable(Set<String> tableFullNames, Set<String> columnNames) {
            this.tableFullNames = tableFullNames;
            this.columnNames = columnNames;
        }

        public Set<String> getTableFullNames() {
            return tableFullNames;
        }

        public Set<String>  getDbNames() {
            if (CollectionUtils.isNotEmpty(tableFullNames)) {
                Set<String> dbNames = new HashSet<>(tableFullNames.size());
                for (String tableFullName : tableFullNames) {
                    if (tableFullName.contains(".")) {
                        dbNames.add(tableFullName.split("\\.")[0]);
                    }
                }
                return dbNames;
            }
            return null;
        }
        public Set<String> getTableNames() {
            if (CollectionUtils.isNotEmpty(tableFullNames)) {
                Set<String> tableNames = new HashSet<>(tableFullNames.size());
                for (String tableFullName : tableFullNames) {
                    if (tableFullName.contains(".")) {
                        String[] array = tableFullName.split("\\.");
                        if (array.length == 3) {
                            tableNames.add(tableFullName.split("\\.")[1]);
                        } else if (array.length == 2) {
                            tableNames.add(tableFullName.split("\\.")[1]);
                        }
                    }else{
                        tableNames.add(tableFullName);
                    }

                }
                return tableNames;
            }
            return null;
        }

        public Set<String> getColumnNames() {
            if (CollectionUtils.isNotEmpty(columnNames)) {
                Set<String> columnNames = new HashSet<>(this.columnNames.size());
                for (String columnName : this.columnNames) {
                    if (columnName.contains(".")) {
                        String[] array = columnName.split("\\.");
                        if (array.length == 3) {
                            columnNames.add(columnName.split("\\.")[2]);
                        }else if (array.length == 2) {
                            columnNames.add(columnName.split("\\.")[1]);
                        }
                    }else{
                        columnNames.add(columnName);
                    }

                }
                return columnNames;
            }
            return  null;
        }
    }


}
